;;; esql-mode.el --- A major emacs mode for editing ESQL files

;; Version: 0.1.0
;; Author: AlexDL
;; Url: https://notabug.org/alexdl/esql-mode
;; Keywords: languages

;;; Commentary:
;;; Code:
(defvar esql-font-lock-defaults nil "Font lock defaults for `esql-mode'.")
(setq esql-font-lock-defaults
      (let* (
              (esql-types '("BOOLEAN" "BOOL" "CHARACTER" "CHAR" "INTEGER" "INT"
                            "REFERENCE TO" "REFERENCE" "REF" "BLOB" "ROW"
                            "DECIMAL"))
              (esql-functions '("CAST" "FIELDNAME" "FIELDVALUE" "TRIM"
                                "SUBSTRING" "LENGTH" "CARDINALITY"
                                "FILDTYPE" "VALUES"))
              (esql-keywords '("BROKER" "SCHEMA"
                               "CREATE" "COMPUTE" "MODULE"
                               "CALL" "FUNCTION" "PROCEDURE"
                               "RETURNS" "RETURN"
                               "NAME" "VALUE" "DOMAIN"
                               "TRUE" "FALSE" "IS" "NOT" "NULL"
                               "DECLARE" "SET" "DEFAULT"
                               "ELSEIF" "IF" "THEN" "ELSE" "END"
                               "FROM" "FOR"
                               "AND" "OR" "OF"
                               "WHILE" "DO" "BEGIN"
                               "IN" "OUT" "INOUT" "AS" "CCSID"
                               "MOVE" "NEXTSIBLING" "FIRSTCHILD" "LASTCHILD"
                               "CURRENT_TIMESTAMP"
                               "THROW" "USER" "EXCEPTION" "MESSAGE"
                               "PROPAGATE" "TO" "LABEL" "DELETE" "NONE"
                               "FORMAT"))
              ;; generate regex string for each category of keywords
              (esql-types-regexp (regexp-opt
                                  (append esql-types
                                          (mapcar 'downcase esql-types))
                                  'words ))
              (esql-functions-regexp (regexp-opt
                                      (append esql-functions
                                              (mapcar 'downcase esql-functions))
                                      'words))
              (esql-keywords-regexp (regexp-opt
                                     (append esql-keywords
                                             (mapcar 'downcase esql-keywords))
                                     'words))
              ;(esql-user-functions-regexp "\\([-A-Za-z0-9]+?\\)[[:space:]\(]")
              (esql-identifier-regexp "\"\\([^\"]+\\)\""))
      `(
        (,esql-types-regexp . font-lock-type-face)
        (,esql-functions-regexp . font-lock-function-name-face)
        ;(,esql-user-functions-regexp . font-lock-function-name-face)
        (,esql-keywords-regexp . font-lock-keyword-face)
        (,esql-identifier-regexp . font-lock-builtin-face)
      )))

(defvar esql-mode-syntax-table nil "Syntax table for `esql-mode'.")

(setq esql-mode-syntax-table
      (let ( (table (make-syntax-table)))
        ;; comment style “/* … */”
        (modify-syntax-entry ?\/ ". 14" table)
        (modify-syntax-entry ?* ". 23" table)
        ;; comment style "-- .."
        (modify-syntax-entry ?\- ". 12b" table)
        (modify-syntax-entry ?\n "> b" table)
        ;; strings
        (modify-syntax-entry ?' "\"" table)
        ;; treat "" as identifiers, not strings
        ;(modify-syntax-entry ?\" "'" table)
        table))


(define-derived-mode esql-mode fundamental-mode "esql"
  (setq font-lock-defaults '((esql-font-lock-defaults)))
  (setq-mode-local indent-tabs-mode nil)
  (setq-mode-local tab-width 4)
  (setq-mode-local indent-line-function 'insert-tab)
  )

(provide 'esql-mode)
;;; esql-mode.el ends here
